package com.ruoyi.master.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.ai.coze.service.ChatService;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.master.domain.TTask;
import com.ruoyi.master.domain.TTaskUp;
import com.ruoyi.master.domain.TWechatUsers;
import com.ruoyi.master.domain.WeightDriftRateVO;
import com.ruoyi.master.mapper.TTaskMapper;
import com.ruoyi.master.service.ITTaskService;
import com.ruoyi.master.service.ITTaskUpService;
import com.ruoyi.master.service.ITWechatUsersService;
import com.ruoyi.master.util.TaskStatusEnum;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.domain.WxText;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 任务Service业务层处理
 *
 * @author jiandan
 * @date 2024-06-27
 */
@Service
public class TTaskServiceImpl implements ITTaskService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private TTaskMapper tTaskMapper;

    @Autowired
    private ITWechatUsersService wechatUsersService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private ITTaskUpService taskUpService;

    @Autowired
    private ChatService chatService;

    @Value("${coze.bot-id}")
    private String botID;

    /**
     * 查询任务
     *
     * @param taskId 任务主键
     * @return 任务
     */
    @Override
    public TTask selectTTaskByTaskId(Long taskId) {
        return tTaskMapper.selectTTaskByTaskId(taskId);
    }

    /**
     * 查询任务列表
     *
     * @param tTask 任务
     * @return 任务
     */
    @Override
    public List<TTask> selectTTaskList(TTask tTask) {
        return tTaskMapper.selectTTaskList(tTask);
    }

    /**
     * 查询开放任务列表
     *
     * @param tTask 任务
     * @return 任务集合
     */
    @Override
    public List<TTask> surfingList(TTask tTask) {
        tTask.setIsOpen("1");
        tTask.setStatus(TaskStatusEnum.NORMAL.getValue());
        List<TTask> rs = tTaskMapper.surfingList(tTask);
        return rs;
    }

    /**
     * 查询Pin任务列表
     *
     * @param tTask 任务
     * @return 任务
     */
    @Override
    public List<TTask> selectPinList(TTask tTask) {
        tTask.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
        tTask.setStatus(TaskStatusEnum.NORMAL.getValue());
        return tTaskMapper.selectTTaskList(tTask);
    }

    /**
     * 新增任务
     *
     * @param tTask 任务
     * @return 结果
     */
    @Override
    public int insertTTask(TTask tTask) {
        tTask.setCreateTime(DateUtils.getNowDate());
        tTask.setCreateBy(SecurityUtils.getUserId().toString());
        return tTaskMapper.insertTTask(tTask);
    }

    /**
     * 修改任务
     *
     * @param tTask 任务
     * @return 结果
     */
    @Override
    public int updateTTask(TTask tTask) {
        tTask.setUpdateTime(DateUtils.getNowDate());
        return tTaskMapper.updateTTask(tTask);
    }

    /**
     * 批量删除任务
     *
     * @param taskIds 需要删除的任务主键
     * @return 结果
     */
    @Override
    public int deleteTTaskByTaskIds(Long[] taskIds) {
        return tTaskMapper.deleteTTaskByTaskIds(taskIds);
    }

    /**
     * 删除任务信息
     *
     * @param taskId 任务主键
     * @return 结果
     */
    @Override
    public int deleteTTaskByTaskId(Long taskId) {
        return tTaskMapper.deleteTTaskByTaskId(taskId);
    }

    /**
     * 处理来自微信的任务
     * @param wxText
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public String insertTaskFromWechat(WxText wxText) {
        logger.info("-----处理来自微信的任务-----");
        String rs = "";
        if (wxText != null) {
            String openid = wxText.getFromOpenId();
            String sysUserId = this.getSysUserByOpenid(openid);
            SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String content = wxText.getContent();
            //如果没有指定任务标签，则由AI处理
            if(!wxText.getContent().contains("#")){
                try {
                    content = this.callAI(wxText.getContent(), sysUserId, this.botID);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            //如果AI返回的结果没有带标签，则加上默认标签
            if(!content.contains("#")){
                content = "#随手记 " + content;
            }
            //笔记入库
            rs = this.insertTask(content, sysUserId, wxText.getCreateTimeL());
        }
        return rs;
    }

    private String insertTask(String content,String sysUserId,Long createTime) {
        String rs = "";
        String taskContent = this.getTask(content);
        // 查看任务是否存在
        TTask tTask = this.selectTTaskByTaskContentAndCreater(null, taskContent, sysUserId);
        Map<String, String> taskUpMap = this.getDurationMin(content);
        logger.info(":微信content:"+content);
        logger.info(":taskUpMap:"+taskUpMap.get("durationMin"));
        logger.info(":remark:"+taskUpMap.get("remark"));
        int durationMin = 0;
        int upMin = Integer.parseInt(taskUpMap.get("durationMin").toString());
        Long taskId = null;
        //如果任务不存在，则需要添加
        if (tTask == null) {
            tTask = new TTask();
            tTask.setCreateTime(new Date(createTime * 1000L));
            tTask.setRemark(content);
            tTask.setDurationMin(durationMin + upMin);
            tTask.setTaskContent(taskContent);
            tTask.setCreateBy(sysUserId);
            tTaskMapper.insertTTask(tTask); //添加任务
            taskId = tTask.getTaskId();

        } else {  //如果任务存在，则进行时长记录的添加，并且将总时长增加
            taskId = tTask.getTaskId();
            List<TTaskUp> tTaskUps = tTask.getTTaskUps();
            for (TTaskUp tTaskUp : tTaskUps) {
                durationMin += tTaskUp.getUpMin();
            }
            tTask.setDurationMin(durationMin + upMin);
            tTask.setUpdateTime(new Date());
            tTask.setRemark(taskUpMap.get("remark"));
            tTaskMapper.updateTTask(tTask);
        }
        TTaskUp tTaskUp = new TTaskUp();
        tTaskUp.setTaskId(taskId);
        tTaskUp.setUpNotes(taskUpMap.get("remark"));
        tTaskUp.setUpMin(upMin);
        tTaskUp.setCreateBy(sysUserId);
        tTaskUp.setCreateTime(new Date(createTime * 1000L));
        taskUpService.insertTTaskUp(tTaskUp);
        if (upMin > 0) {
            rs = "【"+content+"】任务时长增长" + upMin + "分钟";
        }else {
            rs = "【"+content+"】已记录";
        }
        return rs;
    }

    /**
     * 根据openid获取系统用户id，如果用户不存在则新增用户且绑定openid
     * @param openid
     * @return
     */
    private String getSysUserByOpenid(String openid) {
        //查看微信用户是否存在，不存在则新增
        TWechatUsers wechatUsers = wechatUsersService.selectTWechatUsersByOpenid(openid);
        String sysUserId = "";
        if (wechatUsers == null) {
            Long uuid = new Date().getTime();
            SysUser sysUser = new SysUser();
            sysUser.setUserId(uuid);
            sysUser.setUserName(uuid.toString());
            sysUser.setNickName("momo");
            sysUser.setPassword(SecurityUtils.encryptPassword(uuid.toString()));
            sysUser.setCreateBy("system-wechat");
            R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); //创建临时用户
            if (R.FAIL == registerResult.getCode()) {
                throw new ServiceException(registerResult.getMsg());
            }
            sysUserId = uuid.toString();
            wechatUsers = new TWechatUsers();
            wechatUsers.setSysUserId(uuid);
            wechatUsers.setOpenid(openid);
            wechatUsers.setUserId(uuid);
            wechatUsersService.insertTWechatUsers(wechatUsers); //创建微信用户
        } else {
            sysUserId = Long.toString(wechatUsers.getSysUserId());
        }
        return sysUserId;
    }

    /**
     * 保存来自移动端的任务
     *
     * @param tTask
     * @return 结果
     */
    @Override
    public int insertTaskFromApp(TTask tTask) {
        logger.info("-----处理来自移动端的任务-----");
        int rs = 0;
        String sysUserId = SecurityUtils.getUserId().toString();
        String taskContent = tTask.getTaskContent().split(" ")[0].replaceAll("#", "");
        String remark = this.getRemark(tTask.getTaskContent());
        // 查看任务是否存在
        TTask oldTask = this.selectTTaskByTaskContentAndCreater(null, taskContent, sysUserId);
        int durationMin = 0;
        int upMin = tTask.getDurationMin() == null ? 0 : tTask.getDurationMin();
        Long taskId = null;
        //如果任务不存在，则需要添加
        if (oldTask == null) {
            tTask.setCreateTime(DateUtils.getNowDate());
            tTask.setUpdateTime(DateUtils.getNowDate());
            tTask.setRemark(remark);
            tTask.setDurationMin(durationMin + upMin);
            tTask.setTaskContent(taskContent);
            tTask.setCreateBy(sysUserId);
            tTask.setCreateName(SecurityUtils.getUsername());
            tTaskMapper.insertTTask(tTask); //添加任务
            taskId = tTask.getTaskId();

        } else {  //如果任务存在，则进行时长记录的添加，并且将总时长增加
            taskId = oldTask.getTaskId();
            List<TTaskUp> tTaskUps = oldTask.getTTaskUps();
            for (TTaskUp tTaskUp : tTaskUps) {
                durationMin += tTaskUp.getUpMin();
            }
            oldTask.setDurationMin(durationMin + upMin);
            oldTask.setUpdateTime(DateUtils.getNowDate());
            oldTask.setRemark(remark);
            oldTask.setStrategyId(tTask.getStrategyId());
            oldTask.setCreateName(SecurityUtils.getUsername());
            tTaskMapper.updateTTask(oldTask);
        }
        TTaskUp tTaskUp = new TTaskUp();
        tTaskUp.setTaskId(taskId);
        tTaskUp.setUpMin(upMin);
        tTaskUp.setUpNotes(remark);
        tTaskUp.setCreateBy(sysUserId);
        tTaskUp.setCreateTime(DateUtils.getNowDate());
        tTaskUp.setUpdateTime(DateUtils.getNowDate());
        rs = taskUpService.insertTTaskUp(tTaskUp);
        return rs;
    }

    /**
     * 根据任务标签获取任务和对应的任务时长添加记录
     *
     * @param taskContent
     * @return
     */
    @Override
    public TTask selectTTaskByTaskContentAndCreater(Long taskId, String taskContent, String createBy) {
        TTask tTask = tTaskMapper.selectTTaskByTaskContentAndCreater(taskId, taskContent, createBy);
        return tTask;
    }

    /**
     * 获取用户记录下来的总时长
     *
     * @return 总时长
     */
    @Override
    public Long totalDurationMin() {
        Long rs = tTaskMapper.totalDurationMin(TaskStatusEnum.DELETE.getValue(), SecurityUtils.getUserId().toString());
        return rs;
    }

    @Override
    public List<TTask> selectTodayDuration(TTask tTask) {
        if(tTask == null){
            tTask = new TTask();
        }
        tTask.setCreateBy(SecurityUtils.getUserId().toString());
        tTask.setStartDate(DateUtils.getDate());
        List<TTask> list = tTaskMapper.selectTodayDuration(tTask);
        return list;
    }

    @Override
    public int editWeightByTaskId(TTask tTask) {
        Integer rs = 0;
        TTask query = new TTask();
        query.setCreateBy(SecurityUtils.getUserId().toString());
        List<TTask> tTasks = tTaskMapper.selectTTaskList(query);
        Integer weights = tTasks.stream()
                .filter(Objects::nonNull) // 确保流中的元素不是null
                .filter(a -> a.getWeight() != null && a.getWeight() > 0) // 确保weight不是null且大于0
                .filter(a -> a.getStatus() != "20")
                .filter(a -> a.getTaskId() != Integer.parseInt(tTask.getTaskId().toString()))
                .mapToInt(a -> a.getWeight()) // 使用mapToInt来处理Integer类型的weight
                .sum();
        if(weights + tTask.getWeight() > 100){
            return weights;
        }else{
            rs = tTaskMapper.updateTTask(tTask);
            if(rs > 0){
                rs = -1;
            }
        }
        return rs;
    }

    /**
     * 权重任务偏离度计算
     *
     * @param timeDimension 默认为WEEK
     * @param taskId
     * @return
     */
    @Override
    public List<WeightDriftRateVO> weightDriftRate(String timeDimension, Long taskId) {
        TTask queryTask = new TTask();
        if("MONTH".equals(timeDimension)){
            //
        }else{
            Date endUpdateDate = new Date();
            Date startUpdateDate = DateUtils.addDays(endUpdateDate,-14);
            queryTask.setStartUpdateDate(DateUtils.parseDateToStr("yyyy-MM-dd",startUpdateDate));
            queryTask.setEndUpdateDate(DateUtils.parseDateToStr("yyyy-MM-dd",endUpdateDate));
        }
        System.out.println("SecurityUtils.getUserId():"+SecurityUtils.getUserId());
        queryTask.setCreateBy(SecurityUtils.getUserId().toString());
//        queryTask.setCreateBy("1");
        if(taskId != null){
            queryTask.setTaskId(taskId);
        }
        queryTask.setStatus(TaskStatusEnum.NORMAL.getValue());
        //查找开始到结束日期内的所有任务，并统计每天单项任务的时长、每天总时长、
        List<WeightDriftRateVO> driftRateList = tTaskMapper.selectWeightDriftRate(queryTask);
        float sumMin = 0; //总时长
        float sumWeightMin = 0; //带权重的任务总时长
        float sumNoweightMin = 0; //不带权重的任务总时长
        float taskSumMin = 0;//指定的任务时长
        float weight = 0;//权重
        String taskContent = "";//任务
        List<WeightDriftRateVO> driftRateRs = new ArrayList<>();
        if(driftRateList != null && driftRateList.size() > 0){
            for(int i=0;i< driftRateList.size();i++){
                WeightDriftRateVO vo = driftRateList.get(i);
                WeightDriftRateVO rs = new WeightDriftRateVO();
                if(vo.getWeight() > 0) {
                    weight = vo.getWeight();
                    taskContent = vo.getTaskContent();
                }
                sumMin += vo.getSumMin();
                sumWeightMin += vo.getSumWeightMin();
                sumNoweightMin += vo.getSumNoweightMin();
                taskSumMin += vo.getTaskSumMin();
                rs.setCdate(vo.getCdate());
                rs.setTaskId(taskId);
                rs.setTaskContent(taskContent);
                rs.setWeight(weight);
                rs.setSumMin(sumMin);
                rs.setSumWeightMin(sumWeightMin);
                rs.setSumNoweightMin(sumNoweightMin);
                rs.setTaskSumMin(taskSumMin);
                if(sumMin > 0) {
                    //计算总偏离度
                    BigDecimal driftRate = new BigDecimal((taskSumMin / sumMin) - (weight / 100))
                            .setScale(4, BigDecimal.ROUND_HALF_UP);
                    rs.setDriftRate(driftRate);
                    //计算带权重的任务偏离度
                    BigDecimal sumWeightDriftRate = new BigDecimal((sumWeightMin / sumMin) - (sumMin / 1440))
                            .setScale(4, BigDecimal.ROUND_HALF_UP);
                    rs.setSumWeightDriftRate(sumWeightDriftRate);
                }
                if(sumWeightMin > 0){
                    //计算权重内偏离度
                    BigDecimal weightDriftRate = new BigDecimal((taskSumMin / sumWeightMin) - (weight / 100))
                            .setScale(4, BigDecimal.ROUND_HALF_UP);
                    rs.setWeightDriftRate(weightDriftRate);
                }
                driftRateRs.add(rs);
            }
        }

        // 如果任务id为空，默认计算整体权重任务的偏离度
        // 返回权重任务的偏离度，
        return driftRateRs;
    }


    /**
     * 根据文本获取任务标签
     *
     * @param content
     * @return
     */
    private String getTask(String content) {
        TTask tTask = new TTask();
        String[] contents = content.split("\\s+");
        if (StringUtils.contains(contents[0], "#")) {
            return contents[0].replace("#", "");
        }
        return "";
    }

    /**
     * 根据文本获取任务标签
     *
     * @param content
     * @return
     */
    private String getRemark(String content) {
        TTask tTask = new TTask();
        String[] contents = content.split(" ");
        if (contents.length > 1) {
            contents = ArrayUtil.remove(contents, 0);
            return ArrayUtil.join(contents, " ").trim();
        }
        return "";
    }

    /**
     * 根据正文进行切分，获取任务的新增时间，单位转换为分钟
     *
     * @param content
     * @return
     */
    public Map<String ,String > getDurationMin(String content) {
        Map<String ,String> rsmap = new HashMap<>();
        String[] contents = content.split("\\s",2);
        Long durationMin = 0L;
        String remark = "";
        if (ArrayUtils.isNotEmpty(contents)) {
            // 修改后的正则表达式（支持 `30m`、`1h30m`、`2h` 等格式）
            String regex = "\\d+(?:H|h|小时|时)?(?:\\d*(?:M|m|分|分钟))?";

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(contents[1]);
            remark = contents[1].replaceAll(regex,"");
            while (matcher.find()) {
                System.out.println("Extracted: " + matcher.group());  // 输出: Extracted: 1h
                String tmp = matcher.group();
                if (StringUtils.containsAnyIgnoreCase(tmp, "h", "小时", "时")
                        && StringUtils.containsAnyIgnoreCase(tmp, "m", "分", "分钟")) {
                    String[] hours = tmp.split("H|h|小时|时|M|m|分|分钟");
                    durationMin += Long.parseLong(hours[0].replaceAll("[^0-9]]", "")) * 60;
                    durationMin += Long.parseLong(hours[1].replaceAll("[^0-9]]", ""));
                } else if (StringUtils.containsAnyIgnoreCase(tmp, "h", "小时", "时")) {
                    String[] hours = tmp.split("H|h|小时|时");
                    durationMin += Long.parseLong(hours[0].replaceAll("[^0-9]]", "")) * 60;
                } else if (StringUtils.containsAnyIgnoreCase(tmp, "m", "分", "分钟")) {
                    String[] hours = tmp.split("M|m|分|分钟");
                    durationMin += Long.parseLong(hours[0].replaceAll("[^0-9]]", ""));
                }
            }
            rsmap.put("durationMin", String.valueOf(durationMin));
            rsmap.put("remark", remark);
        }
        return rsmap;
    }

    private boolean isValidDuration(String str) {
        String regex = "^\\d+(H|h|小时|时|M|m|分|分钟)$";
        return str.matches(regex);
    }

    public String callAI(String content, String userId,String botID) throws Exception{
        String reply = chatService.chat(content, userId, botID);
        return reply;
    }

}
